#include <map>
#include <string>
#include "Aurelio.h"
#include "WellSizedVector.h"
#include "Hasher.h"
#include <iostream>

using namespace std;

Aurelio::Aurelio() {
	delimiters = " ,\n\t\r.-";
}

//para primeira passada, vai apenas contando as palavras
void Aurelio::updateDictionarySizes (string str)  {
	while (!(str == "") ) {
		unsigned long long nextWord = getNewWordHash(str);
		if (noRepetitionHash[nextWord] == false) {
			noRepetitionHash[nextWord] = true;
			wordDictionary[nextWord].incSize();
		}
	}	
	noRepetitionHash.clear();
}


void Aurelio::printDictionary() {
	map<unsigned long long, WellSizedVector>::iterator it;
	for (it = wordDictionary.begin(); it != wordDictionary.end(); it++) {
		cout << "Palavra " << Hasher::reverseAbcHash(it->first) << " \t" << (it->second).getSize() << endl;
	}
}


void Aurelio::clearDictionary() {
	wordDictionary.clear();
}

unsigned long long Aurelio::getNewWordHash(string & str) {
	string word = "";
	do {
//		cout << "." << endl;
		uint end = str.find_first_of(delimiters.c_str());
		word = str.substr(0, end);
		str = str.substr(end+1, str.size()-(end+1));
//		cout << "word = " << word << endl;
//		cout << "Mudei " << str << " tamanho: " << str.size() << endl;
	}while ( word == "" );
//	cout << "Peguei " << word << " tamanho: " << word.size() << endl;
//	cout << "A string restante eh " << str << endl;
//	cout << endl;
	for (uint i = 0; i < word.size(); i++)
			word[i] = tolower(word[i]);
	return Hasher::abcHash(word);
}

void Aurelio::initializeVectors() {
	map<unsigned long long, WellSizedVector>::iterator it;
	for (it = wordDictionary.begin(); it != wordDictionary.end(); it++)
		(it->second).initializeVector();
}


//segunda passada, insere o id dos documentos
void Aurelio::updateDictionary (string str, uint id)  {
	uint myPosition = 0;
	while (!(str == "") ) {
//		cout << "str: " << str << endl;
		unsigned long long nextWord = getNewWordHash(str);
		if (lastPositionHash[nextWord] == 0) {
//			wordDictionary[nextWord].put(id, myPosition);
			tempDictionary[nextWord].push_back(myPosition);
		}
		else {
//			cout << "Palavra: " << nextWord << endl;
			unsigned short diff = myPosition - (lastPositionHash[nextWord]-1);//-1 acochambrativo
//			wordDictionary[nextWord].add(id, diff ); 
//			cout << "diff: " << diff << endl;
			tempDictionary[nextWord].push_back(diff);
		}
		lastPositionHash[nextWord] = ++myPosition;
	}
	std::map< unsigned long long, std::list<unsigned short> >::iterator it;
	for (it = tempDictionary.begin(); it != tempDictionary.end(); it++) {
//		cout << "size: " << (it->second).size() << endl;
//		cout << "first: " << Hasher::reverseAbcHash(it->first) << " second: " << (*((it->second).begin())) << endl;
//		cout << Hasher::reverseAbcHash(it->first) << endl;
		wordDictionary[it->first].add(id, &(it->second) );
	}
	tempDictionary.clear();
	lastPositionHash.clear();
}

void Aurelio::printFullDictionary() {
	map<unsigned long long, WellSizedVector>::iterator it;
	for (it = wordDictionary.begin(); it != wordDictionary.end(); it++) {
		cout << "Palavra \"" << Hasher::reverseAbcHash(it->first) << "\" \tQuantidade: " << (it->second).getVectorSize() << endl;
		cout << "Presente nos documentos: " << (it->second).listDocs() << endl;
		cout << endl;
	}
}
